home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / DevCon / Milan_1991 / Devcon91.1 / Libraries / Intuition / other_examples / PubSc / textmsg.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-01  |  4.6 KB  |  244 lines

  1. /* tmsg.c -- text message area    :ts=4 */
  2.  
  3. /*
  4. Copyright (c) 1989 Commodore-Amiga, Inc.
  5.  
  6. Executables based on this information may be used in software
  7. for Commodore Amiga computers. All other rights reserved.
  8. This information is provided "as is"; no warranties are made.
  9. All use is at your own risk, and no liability or responsibility
  10. is assumed.
  11. */
  12.  
  13. #include "sysall.h"
  14. #include "tmsg.h"
  15.  
  16. #define D(x)    ;
  17. #define DTLE(x)    ;
  18. #define DTF(x)    ;
  19.  
  20. struct TextMsg    *
  21. CreateTextMsg( totalchars )
  22. {
  23.     struct TextMsg    *tm;
  24.  
  25.     if ( tm =  (struct TextMsg *) AllocMem(
  26.         sizeof (struct TextMsg) + totalchars, MEMF_CLEAR) )
  27.     {
  28.         tm->tm_Buffer = (UBYTE *) (tm + 1);
  29.         tm->tm_BufSize = totalchars;
  30.         LimitTextMsg( tm, -1 );
  31.     }
  32.     return ( tm );
  33. }
  34.  
  35. DeleteTextMsg( tm, num )
  36. struct TextMsg    *tm;
  37. {
  38.     struct TextMsg    *next;
  39.     while ( tm && num-- )
  40.     {
  41.         next = tm->tm_Next;
  42.         FreeMem( tm, (long) sizeof *tm + tm->tm_BufSize );
  43.         tm = next;
  44.     }
  45. }
  46.  
  47. /* support only one-liners for now    */
  48. ChangeTextMsg( rp, tm, str, p1, p2, p3, p4, p5, p6  )
  49. struct RastPort    *rp;
  50. struct TextMsg    *tm;
  51. UBYTE            *str;
  52. {
  53.     D( printf("CTM: erase, rp %lx, tm %lx\n", rp, tm ) );
  54.     if ( rp )  EraseTextMsg( rp, tm, 1 );
  55.  
  56.     if ( str ) sprintf( tm->tm_Buffer, str, p1, p2, p3, p4, p5, p6 );
  57.     else        tm->tm_Buffer[ 0 ] = '\0';
  58.  
  59.     if ( rp )    RefreshTextMsg( rp, tm, 1 );
  60. }
  61.  
  62. TextMsgSize( rp, tm, widthp, heightp )
  63. struct RastPort        *rp;
  64. struct TextMsg        *tm;
  65. UWORD                *widthp;
  66. UWORD                *heightp;
  67. {
  68.     struct Rectangle    tmrect;
  69.     TextMsgExtent( rp, tm, &tmrect );
  70.  
  71.     if ( widthp ) *widthp = tmrect.MaxX - tmrect.MinX + 1;
  72.     if ( heightp ) *heightp = tmrect.MaxY - tmrect.MinY + 1;
  73. }
  74.  
  75.  
  76. TextMsgExtent( rp, tm, rect )
  77. struct RastPort        *rp;
  78. struct TextMsg        *tm;
  79. struct Rectangle    *rect;
  80. {
  81.     D( printf("TME: rp %lx tm %lx rect %lx\n", rp, tm, rect ) );
  82.  
  83.     rect->MinX = rect->MaxX = tm->tm_Left;
  84.     rect->MinY = rect->MaxY = tm->tm_Top;
  85.  
  86.     rect->MaxY += rp->TxHeight - 1;
  87.     rect->MaxX += textLength( rp, tm->tm_Buffer) - 1;
  88.  
  89.     D( printf("TME: extent %d %d %d %d\n",
  90.         rect->MinX, rect->MinY, rect->MaxX, rect->MaxY ) );
  91.  
  92. }
  93.  
  94. /*
  95.  * -1 means no limit
  96.  */
  97. LimitTextMsg( tm, limitwidth )
  98. struct TextMsg    *tm;
  99. {
  100.  
  101.     tm->tm_LimitWidth = limitwidth;
  102. }
  103.  
  104.  
  105. /*
  106.  * num = -1 means do all
  107.  */
  108. RefreshTextMsg( rp, tm, num )
  109. struct RastPort    *rp;
  110. struct TextMsg    *tm;
  111. {
  112.     int    numchars;    /* clip number of chars to fit    */
  113.  
  114.     while ( tm && num-- )
  115.     {
  116.         numchars = textFit( rp, tm->tm_LimitWidth, tm->tm_Buffer);
  117.         DTF( printf("RTM: numchars: %d, limit %d\n",
  118.             numchars, tm->tm_LimitWidth ) );
  119.  
  120.         Move( rp, (long) tm->tm_Left, (long) tm->tm_Top + rp->TxBaseline );
  121.         SetAPen( rp, 1L );
  122.         SetDrMd( rp, (long) JAM1 );
  123.         Text( rp, tm->tm_Buffer, (long) numchars );
  124.  
  125.         tm = tm->tm_Next;
  126.     }
  127. }
  128.  
  129.  
  130. PositionTextMsg( tm, l, t )
  131. struct TextMsg    *tm;
  132. {
  133.     tm->tm_Left = l;
  134.     tm->tm_Top = t;
  135. }
  136.  
  137.  
  138. /*
  139.  * num = -1 means do all
  140.  */
  141. EraseTextMsg( rp, tm, num )
  142. struct RastPort    *rp;
  143. struct TextMsg    *tm;
  144. {
  145.     struct Rectangle    tmrect;
  146.     int    limitmaxx;
  147.  
  148.     while ( tm && num-- )
  149.     {
  150.         D( printf("ETM, rp %lx tm %lx\n", rp, tm ) );
  151.  
  152.         TextMsgExtent( rp, tm, &tmrect );
  153.         if ( tm->tm_LimitWidth > 0 )
  154.         {
  155.             limitmaxx = tmrect.MinX + tm->tm_LimitWidth - 1;
  156.             DTF( printf("maxx %d, limitmaxx %d\n", tmrect.MaxX, limitmaxx));
  157.             tmrect.MaxX = jmin( tmrect.MaxX, limitmaxx );
  158.         }
  159.  
  160.         D( printf("ETM: extent %d %d %d %d\n",
  161.             tmrect.MinX, tmrect.MinY, tmrect.MaxX, tmrect.MaxY ) );
  162.  
  163.         if ( tmrect.MaxX > tmrect.MinX && tmrect.MaxY > tmrect.MinY )
  164.         {
  165.             SetAPen( rp, 0L );
  166.             RectFill( rp, (long) tmrect.MinX, (long) tmrect.MinY,
  167.                           (long) tmrect.MaxX, (long) tmrect.MaxY );
  168.         }
  169.  
  170.         tm = tm->tm_Next;
  171.     }
  172. }
  173.  
  174.  
  175. /** utility routines    **/
  176. textLength( rp, str )
  177. struct RastPort    *rp;
  178. UBYTE            *str;
  179. {
  180.     DTLE( printf("tL: string <%s> length: %d\n", str, strlen(str) ));
  181.     return ( TextLength( rp, str, (LONG) strlen( str ) ) );
  182. }
  183.  
  184. /*
  185.  * no limit if width <=0 
  186.  */
  187. textFit( rp, width, str )
  188. struct RastPort    *rp;
  189. int        width;
  190. char    *str;
  191. {
  192.     int        i = strlen( str );
  193.  
  194.     if ( width > 0 )
  195.     {
  196.         for ( ; i > 0; --i )
  197.         {
  198.             if ( TextLength( rp, str, (LONG) i ) < width )
  199.             {
  200.                 break;
  201.             }
  202.         }
  203.     }
  204.  
  205.     return( i );
  206. }
  207.  
  208.  
  209. textListExtent( rp, argv, numgad, te )
  210. struct RastPort    *rp;
  211. UBYTE            **argv;
  212. struct Rectangle    *te;
  213. {
  214.  
  215.     int                    width;
  216.  
  217.     DTLE( printf("textListExtent: rp text height: %d\n", rp->TxHeight ));
  218.  
  219.     /* measure text to get largest extent    */
  220.     width = 0;
  221.  
  222.     while ( numgad-- )
  223.     {
  224.         DTLE( printf("tLE:measure string: <%s>\n", *argv));
  225.         width = jmax( width, textLength( rp, *argv ) );
  226.         argv++;
  227.         DTLE( printf("tLE: width %d\n", width ));
  228.     }
  229.  
  230.     te->MinX = te->MinY = 0;
  231.     te->MaxX = width - 1;
  232.     te->MaxY = rp->TxHeight - 1;
  233. }
  234.  
  235. /* I prefer functions to macros here */
  236. jmin( a, b)
  237. {
  238.     return ( (a>b)? b: a );
  239. }
  240. jmax( a, b)
  241. {
  242.     return ( (a<b)? b: a );
  243. }
  244.